#ifndef __MY_UTIL__
#define __MY_UTIL__

#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>

namespace aod
{
    // 一、文件工具类的实现：
    class FileUtil
    {
    private:
        std::string _name; // 文件路径名称
    public:
        FileUtil(std::string name) : _name(name) {}
        ~FileUtil() {}

        // 1、获取文件大小
        size_t Size()
        {
            if (this->Exists() == false)
            {
                return 0;
            }

            struct stat stSize;
            // stat用于获取文件属性，其中的st_size就是文件大小成员
            int ret = stat(_name.c_str(), &stSize);
            if (ret != 0)
            {
                return false;
            }
            return stSize.st_size;
        }
        // 2、判断文件是否存在
        bool Exists()
        {
            // access的F_ok是用来专门用来检测文件是否存在的---存在返回0
            int ret = access(_name.c_str(), F_OK);
            if (ret != 0)
            {
                std::cout << "file is not exists!\n";
                return false;
            }
            return true;
        }
        // 3、读取文件数据到body中
        bool GetConnect(std::string *body)
        {
            std::ifstream ifs;
            ifs.open(_name, std::ios::binary);

            if (ifs.is_open() == false)
            {
                std::cout << "open failed!\n";
                return false;
            }

            size_t flen = this->Size();
            body->resize(flen);

            ifs.read(&(*body)[0], flen);

            if (ifs.good() == false)
            {
                std::cout << "raed failed!\n";
                ifs.close();
                return false;
            }
            ifs.close();
            return true;
        }

        // 4、写入文件到body中
        bool SetConnect(const std::string &body)
        {
            std::ofstream ofs;
            ofs.open(_name, std::ios::binary);

            if (ofs.is_open() == false)
            {
                std::cout << "open failed!\n";
                return false;
            }

            ofs.write(body.c_str(), body.size());

            if (ofs.good() == false)
            {
                std::cout << "write failed!\n";
                ofs.close();
                return false;
            }
            ofs.close();
            return true;
        }
        // 5、创建目录
        bool CreateDirectory()
        {
            if (this->Exists())
                return true;
            mkdir(_name.c_str(), 0777);
            return true;
        }
    };

    // 二、json工具类的实现:

    class JsonUtil
    {
    public:
        // 1、序列化
        static bool Serialize(const Json::Value &value, std::string *str)
        {
            Json::StreamWriterBuilder swb;
            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

            std::stringstream ss;
            int ret = sw->write(value, &ss);

            if (ret != 0)
            {
                std::cout << "Serialize failed" << std::endl;
                return false;
            }
            *str = ss.str();
            return true;
        }

        // 2、反序列化
        static bool Unserialize(const std::string &str, Json::Value *value)
        {
            Json::CharReaderBuilder crb;
            std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

            std::string err;
            bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), value, &err);
            if (ret == false)
            {
                std::cout << "Unserialize failed" << std::endl;
            }
            return true;
        }
    };

}

#endif